<!--
 * @Descripttion: 无限视差滚动
 * @Author: jhw
 * @Date: 2023-05-24 20:29:52
 * @LastEditors: jhw
 * @LastEditTime: 2023-05-24 23:13:55
-->
<template>
  <div class="parallax-demo">
    <div ref="scrollContainer" class="scroll_container"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';

// 定义一个img数组
const images: any = [
  'https://picsum.photos/id/23/800/500',
  'https://picsum.photos/id/24/800/500',
  'https://picsum.photos/id/25/800/500',
  'https://picsum.photos/id/26/800/500',
  'https://picsum.photos/id/27/800/500',
];

// 获取滚动容器
const scrollContainer = ref();

// 当前中间图片的下标
let currentIndex = 0;

// 是否正在滚动
let isScrolling = false;

// 创建图片
const createImage = (index: number) => {
  const imgUrl = images[index];
  const item = document.createElement('div');
  item.classList.add('item');
  item.innerHTML = `<img src="${imgUrl}" alt="" />`;
  scrollContainer.value.appendChild(item);
  return item;
};

// 容器加入图片
const resetElements = () => {
  scrollContainer.value.innerHTML = '';
  // 获取上一张图片索引
  const prevIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
  // 获取下一张图片索引
  const nextIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
  createImage(prevIndex).classList.add('prev');
  createImage(currentIndex).classList.add('cur');
  createImage(nextIndex).classList.add('next');
};

// 监听鼠标滚动事件
const handleMouseWheel = (e: any) => {
  if (e.wheelDelta === 0) {
    return;
  }
  if (isScrolling) {
    return;
  }
  isScrolling = true;
  // 鼠标滚轮向上滚动
  if (e.wheelDelta > 0) {
    scrollContainer.value.classList.add('scroll_up');
    currentIndex--;
    if (currentIndex < 0) {
      currentIndex = images.length - 1;
    }
  } else {
    // 鼠标滚轮向下滚动
    scrollContainer.value.classList.add('scroll_down');
    currentIndex++;
    if (currentIndex > images.length - 1) {
      currentIndex = 0;
    }
  }
};

// 监听动画结束事件
const handleTransitionEnd = () => {
  isScrolling = false;
  scrollContainer.value.classList.remove('scroll_up', 'scroll_down');
  resetElements();
};

onMounted(() => {
  resetElements();
  scrollContainer.value.addEventListener('wheel', handleMouseWheel.bind(this));
  scrollContainer.value.addEventListener('transitionend', handleTransitionEnd.bind(this));
});
</script>

<style lang="scss" scoped>
@import '@/styles/spcially/parallax-demo';

.parallax-demo {
  width: 800px;
  height: 500px;
  overflow: hidden;

  .scroll_container {
    height: 100%;
    width: 100%;
    position: relative;
  }
}
</style>
